package dy.app.component;

import com.alibaba.fastjson2.JSON;
import dy.app.util.CommonUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.util.Map;
import java.util.Objects;

/**
 * 通用 http连接组件
 * Author: cKnight
 * Date: 2024/6/11
 */
@Component
@Slf4j
public class RestHttpComponent {
    @Resource
    private RestTemplate restTemplate;

    /**
     * 返回对应实体类
     * @param url
     * @param clazz
     * @return
     * @param <T>
     */
    public <T> T getForObject(String url, Class<T> clazz) {
        log.info("RestHttpGet调用,url:{}",url);
        return process(()-> Objects.requireNonNull(restTemplate.getForObject(url, clazz)));
    }

    /**
     * 自动拼装 url参数
     * @param url
     * @param params 可为null
     * @param clazz
     * @return
     * @param <T>
     */
    public <T> T getForObject(String url, Map<String,Object> params, Class<T> clazz){
        //自动拼装参数
        url = CommonUtils.transUrl(url,params);
        log.info("RestHttpGet调用,params:{}",params);
        return getForObject(url,clazz);
    }

    /**
     * 自动拼装 url参数
     * 返回全信息
     * @param url
     * @param params
     * @param clazz
     * @return
     * @param <T>
     */
    public <T> ResponseEntity<T> getForEntity(String url, Map<String,Object> params, Class<T> clazz){
        //自动拼装参数
        String finalUrl = CommonUtils.transUrl(url,params);
        log.info("RestHttpGetEntity调用,url:{},params:{}",url,params);
        return process(()->Objects.requireNonNull(restTemplate.getForEntity(finalUrl,clazz)));
    }


    /**
     * 带有头信息的get请求
     * @param url
     * @param params
     * @param headers
     * @param clazz
     * @return
     * @param <T>
     */
    public <T> ResponseEntity<T> getForObject(String url, Map<String,Object> params, HttpHeaders headers, Class<T> clazz){
        String finalUrl = CommonUtils.transUrl(url,params);
        log.info("RestHttpGet调用,url:{},params:{},headers:{}",url,params,headers.toString());
        return process(()-> Objects.requireNonNull(
                restTemplate.exchange(finalUrl, HttpMethod.GET, new HttpEntity<>(headers), clazz)
        ));
    }


    /**
     * 返回 对应实体类的post请求
     * 自动填充 json头信息
     * @param url
     * @param params
     * @param clazz
     * @return
     * @param <T>
     */
    public <T> ResponseEntity<T> postBodyForEntity(String url, Map<String,Object> params, Class<T> clazz){
        return postBodyForEntity(url,params,new HttpHeaders(),clazz);
    }

    /**
     * 带有头信息的post请求 自动填充json信息
     * @param url
     * @param params
     * @param headers
     * @param clazz
     * @return
     * @param <T>
     */
    public <T> ResponseEntity<T> postBodyForEntity(String url, Map<String,Object> params, HttpHeaders headers, Class<T> clazz){
        MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
        headers.setContentType(type);
        headers.add("Accept", MediaType.APPLICATION_JSON.toString());
        log.info("RestHttpPost调用,url:{},params:{},headers:{}",url,params,headers.toString());
        return process(()->
                Objects.requireNonNull(
                        restTemplate.exchange(url
                                ,HttpMethod.POST
                                ,new HttpEntity<>(JSON.toJSONString(params), headers)
                                ,clazz)));
    }



    /**
     * 安全处理
     * @param objectFactory
     * @return
     * @param <T>
     */
    private <T> T process(ObjectFactory<T> objectFactory ){
        try {
            T object = objectFactory.getObject();
            log.info("RestHttp调用,响应结果:{}",object);
            return object;
        }catch (Exception e){
            log.error("RestHttp调用异常:",e);
        }
        return null;
    }
}
